home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 114 / macaddict114.cdr / Software / Utilities / macam.0.8.4.dmg / macam sources / utilities / yuv2rgbOV420.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  10.6 KB  |  292 lines

  1. /*
  2.  macam - webcam app and QuickTime driver component
  3.  Copyright (C) 2002 Matthias Krauss (macam@matthias-krauss.de)
  4.  Copyright (C) 2002 Hiroki Mori
  5.  
  6.  This program is free software; you can redistribute it and/or modify
  7.  it under the terms of the GNU General Public License as published by
  8.  the Free Software Foundation; either version 2 of the License, or
  9.  (at your option) any later version.
  10.  
  11.  This program is distributed in the hope that it will be useful,
  12.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  GNU General Public License for more details.
  15.  
  16.  You should have received a copy of the GNU General Public License
  17.  along with this program; if not, write to the Free Software
  18.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  $Id: yuv2rgbOV420.c,v 1.2 2002/10/28 23:24:33 himori Exp $
  20. */
  21.  
  22. /*
  23.  
  24. This file contains just a raw function body and is intended to be #included from other files, such as yuv2rgb.c
  25.  
  26. The function prototype has to be:
  27.  
  28. void <whatever>(int width, int height, unsigned char *src, unsigned char *dst, long srcRowExtra, long dstRowExtra);
  29.  
  30. */
  31.     unsigned char* s1;                //Source buffer run: y first line
  32.     unsigned char* s2;                //Source buffer run: y second line
  33.     unsigned char* s3;                //Source buffer run: u line
  34.     unsigned char* s4;                //Source buffer run: v line
  35.     unsigned char* d1;                //Destination buffer run: first line
  36.     unsigned char* d2;                //Destination buffer run: first line
  37.     long x,y;                    //loop counters
  38.     long y11,y12,y13,y14,y21,y22,y23,y24;    //The y components in yuv
  39.     long u1,u1g,u1b,u2,u2g,u2b;            //The raw u components and the u differences
  40.     long v1,v1r,v1g,v2,v2r,v2g;            //The raw v components and the v differences
  41.     long r11,g11,b11,r12,g12,b12,r13,g13,b13,r14,g14,b14;    //Destination rgb: first line
  42.     long r21,g21,b21,r22,g22,b22,r23,g23,b23,r24,g24,b24;    //Destination rgb: second line
  43.     long dstRowBytes;                //EXCLUDING the extra part, just the raw data length per row
  44.     unsigned long ul1,ul2,ul3,ul4,ul5,ul6,ul7,ul8;     //Temp vars to access memory
  45.     unsigned short us1, us2;
  46. #ifdef YUV2RGB_ALPHA
  47.     short bpp=4;
  48. #else
  49.     short bpp=3;
  50. #pragma unused(ul4)
  51. #pragma unused(ul8)
  52. #endif
  53.     width/=4;                    //We work in 4 x 2 blocks
  54.     height/=2;
  55.     dstRowBytes=4*bpp*width;
  56.     s1=src;
  57.     s2=src+width*4+srcRowExtra;
  58.     s3=src+width*height*8;
  59.     s4=src+width*height*8+width*height*8/4;
  60.     srcRowExtra=2*srcRowExtra+4*width;        //skip y line since we're working two lines at once
  61.     d1=dst;
  62.     d2=dst+width*4*bpp+dstRowExtra;
  63. #ifndef YUV2RGB_FLIP
  64.     dstRowExtra=2*dstRowExtra+dstRowBytes;    //Extend to skip one line since we're working two lines at once
  65. #else
  66.     dstRowExtra=2*dstRowExtra+3*dstRowBytes;    //From the start of a line to the end of the second next
  67.     d1+=dstRowBytes;
  68.     d2+=dstRowBytes;
  69. #endif
  70.     for (y=height;y;y--) {
  71.         for (x=width;x;x--) {
  72. //Read from source buffer
  73.             ul1=*((unsigned  long*)(s1)); s1+=4;    //Read y in line 1
  74.             ul2=*((unsigned  long*)(s2)); s2+=4;    //Read y in line 2
  75.             us1=*((unsigned  short*)(s3)); s3+=2;    //Read u
  76.             us2=*((unsigned  short*)(s4)); s4+=2;    //Read v
  77. //Extract yuv pixel data
  78.             y11=(ul1&0xff000000)>>16;
  79.             y12=(ul1&0x00ff0000)>>8;
  80.             y13=(ul1&0x0000ff00);
  81.             y14=(ul1&0x000000ff)<<8;
  82.             y21=(ul2&0xff000000)>>16;
  83.             y22=(ul2&0x00ff0000)>>8;
  84.             y23=(ul2&0x0000ff00);
  85.             y24=(ul2&0x000000ff)<<8;
  86.             u1 =((us1&0x0000ff00)>>8)-128;
  87.             u2 =(us1&0x000000ff)-128;
  88.             v1 =((us2&0x0000ff00)>>8)-128;
  89.             v2 =(us2&0x000000ff)-128;
  90. //convert yuv to rgb: calculate difference coefficients
  91.             u1g=u1*88;
  92.             u1b=u1*454;
  93.             v1r=v1*359;
  94.             v1g=v1*183;
  95.             u2g=u2*88;
  96.             u2b=u2*454;
  97.             v2r=v2*359;
  98.             v2g=v2*183;
  99. //convert yuv to rgb: assemble rgb
  100.             r11=(y11+v1r)/256;
  101.             g11=(y11-u1g-v1g)/256;
  102.             b11=(y11+u1b)/256;
  103.             r12=(y12+v1r)/256;
  104.             g12=(y12-u1g-v1g)/256;
  105.             b12=(y12+u1b)/256;
  106.             r13=(y13+v2r)/256;
  107.             g13=(y13-u2g-v2g)/256;
  108.             b13=(y13+u2b)/256;
  109.             r14=(y14+v2r)/256;
  110.             g14=(y14-u2g-v2g)/256;
  111.             b14=(y14+u2b)/256;
  112.             r21=(y21+v1r)/256;
  113.             g21=(y21-u1g-v1g)/256;
  114.             b21=(y21+u1b)/256;
  115.             r22=(y22+v1r)/256;
  116.             g22=(y22-u1g-v1g)/256;
  117.             b22=(y22+u1b)/256;
  118.             r23=(y23+v2r)/256;
  119.             g23=(y23-u2g-v2g)/256;
  120.             b23=(y23+u2b)/256;
  121.             r24=(y24+v2r)/256;
  122.             g24=(y24-u2g-v2g)/256;
  123.             b24=(y24+u2b)/256;
  124. //convert yuv to rgb: check value bounds
  125.             r11=CLAMP(r11,0,255);
  126.             g11=CLAMP(g11,0,255);
  127.             b11=CLAMP(b11,0,255);
  128.             r12=CLAMP(r12,0,255);
  129.             g12=CLAMP(g12,0,255);
  130.             b12=CLAMP(b12,0,255);
  131.             r13=CLAMP(r13,0,255);
  132.             g13=CLAMP(g13,0,255);
  133.             b13=CLAMP(b13,0,255);
  134.             r14=CLAMP(r14,0,255);
  135.             g14=CLAMP(g14,0,255);
  136.             b14=CLAMP(b14,0,255);
  137.             r21=CLAMP(r21,0,255);
  138.             g21=CLAMP(g21,0,255);
  139.             b21=CLAMP(b21,0,255);
  140.             r22=CLAMP(r22,0,255);
  141.             g22=CLAMP(g22,0,255);
  142.             b22=CLAMP(b22,0,255);
  143.             r23=CLAMP(r23,0,255);
  144.             g23=CLAMP(g23,0,255);
  145.             b23=CLAMP(b23,0,255);
  146.             r24=CLAMP(r24,0,255);
  147.             g24=CLAMP(g24,0,255);
  148.             b24=CLAMP(b24,0,255);
  149. //Assemble longs from rgb data
  150. #ifndef YUV2RGB_ALPHA
  151. #ifdef YUV2RGB_FLIP
  152. //3bpp, flipped assembly
  153.             ul3=(((unsigned long)r14)<<24)
  154.                 |(((unsigned long)g14)<<16)
  155.                 |(((unsigned long)b14)<<8)
  156.                 |(((unsigned long)r13));
  157.             ul2=(((unsigned long)g13)<<24)
  158.                 |(((unsigned long)b13)<<16)
  159.                 |(((unsigned long)r12)<<8)
  160.                 |(((unsigned long)g12));
  161.             ul1=(((unsigned long)b12)<<24)
  162.                 |(((unsigned long)r11)<<16)
  163.                 |(((unsigned long)g11)<<8)
  164.                 |(((unsigned long)b11));
  165.             ul7=(((unsigned long)r24)<<24)
  166.                 |(((unsigned long)g24)<<16)
  167.                 |(((unsigned long)b24)<<8)
  168.                 |(((unsigned long)r23));
  169.             ul6=(((unsigned long)g23)<<24)
  170.                 |(((unsigned long)b23)<<16)
  171.                 |(((unsigned long)r22)<<8)
  172.                 |(((unsigned long)g22));
  173.             ul5=(((unsigned long)b22)<<24)
  174.                 |(((unsigned long)r21)<<16)
  175.                 |(((unsigned long)g21)<<8)
  176.                 |(((unsigned long)b21));
  177. #else
  178. //3bpp, unflipped assembly
  179.             ul1=(((unsigned long)r11)<<24)
  180.                 |(((unsigned long)g11)<<16)
  181.                 |(((unsigned long)b11)<<8)
  182.                 |(((unsigned long)r12));
  183.             ul2=(((unsigned long)g12)<<24)
  184.                 |(((unsigned long)b12)<<16)
  185.                 |(((unsigned long)r13)<<8)
  186.                 |(((unsigned long)g13));
  187.             ul3=(((unsigned long)b13)<<24)
  188.                 |(((unsigned long)r14)<<16)
  189.                 |(((unsigned long)g14)<<8)
  190.                 |(((unsigned long)b14));
  191.             ul5=(((unsigned long)r21)<<24)
  192.                 |(((unsigned long)g21)<<16)
  193.                 |(((unsigned long)b21)<<8)
  194.                 |(((unsigned long)r22));
  195.             ul6=(((unsigned long)g22)<<24)
  196.                 |(((unsigned long)b22)<<16)
  197.                 |(((unsigned long)r23)<<8)
  198.                 |(((unsigned long)g23));
  199.             ul7=(((unsigned long)b23)<<24)
  200.                 |(((unsigned long)r24)<<16)
  201.                 |(((unsigned long)g24)<<8)
  202.                 |(((unsigned long)b24));
  203. #endif
  204. #else
  205. //4bpp assembly - no matter if flipped or unflipped
  206.             ul1=0xff000000
  207.                 |(((unsigned long)r11)<<16)
  208.                 |(((unsigned long)g11)<<8)
  209.                 |(((unsigned long)b11));
  210.             ul2=0xff000000
  211.                 |(((unsigned long)r12)<<16)
  212.                 |(((unsigned long)g12)<<8)
  213.                 |(((unsigned long)b12));
  214.             ul3=0xff000000
  215.                 |(((unsigned long)r13)<<16)
  216.                 |(((unsigned long)g13)<<8)
  217.                 |(((unsigned long)b13));
  218.             ul4=0xff000000
  219.                 |(((unsigned long)r14)<<16)
  220.                 |(((unsigned long)g14)<<8)
  221.                 |(((unsigned long)b14));
  222.             ul5=0xff000000
  223.                 |(((unsigned long)r21)<<16)
  224.                 |(((unsigned long)g21)<<8)
  225.                 |(((unsigned long)b21));
  226.             ul6=0xff000000
  227.                 |(((unsigned long)r22)<<16)
  228.                 |(((unsigned long)g22)<<8)
  229.                 |(((unsigned long)b22));
  230.             ul7=0xff000000
  231.                 |(((unsigned long)r23)<<16)
  232.                 |(((unsigned long)g23)<<8)
  233.                 |(((unsigned long)b23));
  234.             ul8=0xff000000
  235.                 |(((unsigned long)r24)<<16)
  236.                 |(((unsigned long)g24)<<8)
  237.                 |(((unsigned long)b24));
  238. #endif
  239. //Output to destination buffer
  240. #ifdef YUV2RGB_FLIP
  241. #ifdef YUV2RGB_ALPHA
  242.             d1-=16;
  243.             *((unsigned long*)(d1+12))=ul1;
  244.             *((unsigned long*)(d1+ 8))=ul2;
  245.             *((unsigned long*)(d1+ 4))=ul3;
  246.             *((unsigned long*)(d1   ))=ul4;
  247.             d2-=16;
  248.             *((unsigned long*)(d2+12))=ul5;
  249.             *((unsigned long*)(d2+ 8))=ul6;
  250.             *((unsigned long*)(d2+ 4))=ul7;
  251.             *((unsigned long*)(d2   ))=ul8;
  252. #else    //YUV2RGB_ALPHA
  253.             d1-=12;
  254.             *((unsigned long*)(d1+ 8))=ul1;
  255.             *((unsigned long*)(d1+ 4))=ul2;
  256.             *((unsigned long*)(d1   ))=ul3;
  257.             d2-=12;
  258.             *((unsigned long*)(d2+ 8))=ul5;
  259.             *((unsigned long*)(d2+ 4))=ul6;
  260.             *((unsigned long*)(d2   ))=ul7;
  261. #endif    //YUV2RGB_ALPHA
  262. #else    //YUV2RGB_FLIP
  263. #ifdef YUV2RGB_ALPHA
  264.             *((unsigned long*)(d1))=ul1;
  265.             *((unsigned long*)(d1+4))=ul2;
  266.             *((unsigned long*)(d1+8))=ul3;
  267.             *((unsigned long*)(d1+12))=ul4;
  268.             d1+=16;
  269.             *((unsigned long*)(d2))=ul5;
  270.             *((unsigned long*)(d2+4))=ul6;
  271.             *((unsigned long*)(d2+8))=ul7;
  272.             *((unsigned long*)(d2+12))=ul8;
  273.             d2+=16;
  274. #else    //YUV2RGB_ALPHA
  275.             *((unsigned long*)(d1))=ul1;
  276.             *((unsigned long*)(d1+4))=ul2;
  277.             *((unsigned long*)(d1+8))=ul3;
  278.             d1+=12;
  279.             *((unsigned long*)(d2))=ul5;
  280.             *((unsigned long*)(d2+4))=ul6;
  281.             *((unsigned long*)(d2+8))=ul7;
  282.             d2+=12;
  283. #endif    //YUV2RGB_ALPHA
  284. #endif    //YUV2RGB_FLIP
  285.         }
  286.         s1+=srcRowExtra;
  287.         s2+=srcRowExtra;
  288.         d1+=dstRowExtra;
  289.         d2+=dstRowExtra;
  290.     }
  291. //End of included, preprocessor-customized code
  292.